package main

import (
	"errors"
)

func Delete[T any](index int, slice []T) ([]T, T, error) {
	if index < 0 || index >= len(slice) {
		var zero T
		return slice, zero, errors.New("Index out of range")
	}
	v := slice[index]
	for i := index; i < len(slice)-1; i++ {
		slice[i] = slice[i+1]
	}
	slice = slice[:len(slice)-1]
	slice = Shrink(slice)
	return slice, v, nil
}

func DeleteWithoutShrink[T any](index int, slice []T) ([]T, T, error) {
	if index < 0 || index >= len(slice) {
		var zero T
		return slice, zero, errors.New("Index out of range")
	}
	v := slice[index]
	for i := index; i < len(slice)-1; i++ {
		slice[i] = slice[i+1]
	}
	slice = slice[:len(slice)-1]
	return slice, v, nil
}

// 如果容量64以下，就不动，
// 256以下， lenF*2.5 < capF 就缩, 留下len * 2
// 其他，lenF*1.5 < capF 就缩， 留下 len * 1.25
func CalcShrinkCap(length int, oldCap int) (newCap int, isShrink bool) {
	if oldCap <= 64 {
		return newCap, false
	}

	lenF, capF := float64(length), float64(oldCap)
	if oldCap <= 256 {
		//lenF*2.5 < capF
		if lenF < capF*0.4 {
			return length * 2, true
		}
	} else {
		//lenF*1.5 < capF
		if lenF < capF*0.6666 {
			return int(lenF * 1.25), true
		}
	}
	return oldCap, false
}

func Shrink[T any](slice []T) []T {
	length, capacity := len(slice), cap(slice)
	newCap, isShrink := CalcShrinkCap(length, capacity)
	if !isShrink {
		return slice
	}
	newSlice := make([]T, length, newCap)
	copy(newSlice, slice)
	return newSlice
}
